package com.kexio.auth.tenant;

import jakarta.servlet.http.HttpServletRequest;

/**
 * 租户解析器接口
 * 
 * 负责从HTTP请求中解析出当前请求对应的租户ID：
 * 1. 支持多种租户信息来源（JWT、Header、URL参数等）
 * 2. 提供灵活的解析策略和优先级配置
 * 3. 支持租户ID的验证和规范化
 * 4. 提供默认租户和异常处理机制
 * 
 * 实现类应该考虑：
 * - 性能优化：缓存解析结果，避免重复计算
 * - 安全性：验证租户ID的合法性，防止恶意请求
 * - 可扩展性：支持新的租户信息来源
 * - 容错性：在解析失败时提供合理的默认行为
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
public interface TenantResolver {
    
    /**
     * 从HTTP请求中解析租户ID
     * 
     * 解析策略（按优先级顺序）：
     * 1. JWT Token中的租户信息（最高优先级）
     * 2. HTTP请求头中的租户信息
     * 3. URL参数中的租户信息
     * 4. 子域名中的租户信息
     * 5. 默认租户ID（最低优先级）
     * 
     * @param request HTTP请求对象
     * @return 解析出的租户ID，保证不为null
     */
    String resolve(HttpServletRequest request);
    
    /**
     * 从HTTP请求中尝试解析租户ID（不使用默认值）
     * 
     * @param request HTTP请求对象
     * @return 解析出的租户ID，如果无法解析则返回null
     */
    String tryResolve(HttpServletRequest request);
    
    /**
     * 获取默认租户ID
     * 
     * @return 默认租户ID
     */
    String getDefaultTenantId();
    
    /**
     * 检查租户ID是否有效
     * 
     * @param tenantId 要检查的租户ID
     * @return true如果有效，false否则
     */
    boolean isValidTenantId(String tenantId);
    
    /**
     * 规范化租户ID
     * 
     * @param tenantId 原始租户ID
     * @return 规范化后的租户ID
     */
    String normalizeTenantId(String tenantId);
    
    /**
     * 获取支持的租户信息来源
     * 
     * @return 支持的来源列表
     */
    java.util.List<TenantSource> getSupportedSources();
    
    /**
     * 租户信息来源枚举
     */
    enum TenantSource {
        /**
         * JWT令牌中的租户信息
         */
        JWT("JWT令牌", 100),
        
        /**
         * HTTP请求头中的租户信息
         */
        HEADER("请求头", 80),
        
        /**
         * URL参数中的租户信息
         */
        PARAMETER("URL参数", 60),
        
        /**
         * 子域名中的租户信息
         */
        SUBDOMAIN("子域名", 40),
        
        /**
         * 默认租户
         */
        DEFAULT("默认租户", 0);
        
        private final String description;
        private final int priority;
        
        TenantSource(String description, int priority) {
            this.description = description;
            this.priority = priority;
        }
        
        public String getDescription() {
            return description;
        }
        
        public int getPriority() {
            return priority;
        }
    }
}
